/*
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at 
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  
 */

using System;
using java = biz.ritter.javapi;
using org.apache.commons.collections;

namespace org.apache.commons.collections.map
{

    /**
     * Decorates another <code>SortedMap</code> to create objects in the map on demand.
     * <p>
     * When the {@link #get(Object)} method is called with a key that does not
     * exist in the map, the factory is used to create the object. The created
     * object will be added to the map using the requested key.
     * <p>
     * For instance:
     * <pre>
     * Factory factory = new Factory() {
     *     public Object create() {
     *         return new Date();
     *     }
     * }
     * SortedMap lazy = Lazy.sortedMap(new HashMap(), factory);
     * Object obj = lazy.get("NOW");
     * </pre>
     *
     * After the above code is executed, <code>obj</code> will contain
     * a new <code>Date</code> instance. Furthermore, that <code>Date</code>
     * instance is mapped to the "NOW" key in the map.
     * <p>
     * <strong>Note that LazySortedMap is not synchronized and is not thread-safe.</strong>
     * If you wish to use this map from multiple threads concurrently, you must use
     * appropriate synchronization. The simplest approach is to wrap this map
     * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw 
     * exceptions when accessed by concurrent threads without synchronization.
     * <p>
     * This class is java.io.Serializable from Commons Collections 3.1.
     *
     * @since Commons Collections 3.0
     * @version $Revision: 7132 $ $Date: 2011-06-04 20:52:33 +0200 (Sa, 04. Jun 2011) $
     * 
     * @author Stephen Colebourne
     * @author Paul Jack
     */
    public class LazySortedMap
            : LazyMap
            , java.util.SortedMap<Object, Object>
    {

        /** Serialization version */
        private static readonly long serialVersionUID = 2715322183617658933L;

        /**
         * Factory method to create a lazily instantiated sorted map.
         * 
         * @param map  the map to decorate, must not be null
         * @param factory  the factory to use, must not be null
         * @throws IllegalArgumentException if map or factory is null
         */
        public static java.util.SortedMap<Object, Object> decorate(java.util.SortedMap<Object, Object> map, Factory factory)
        {
            return new LazySortedMap(map, factory);
        }

        /**
         * Factory method to create a lazily instantiated sorted map.
         * 
         * @param map  the map to decorate, must not be null
         * @param factory  the factory to use, must not be null
         * @throws IllegalArgumentException if map or factory is null
         */
        public static java.util.SortedMap<Object, Object> decorate(java.util.SortedMap<Object, Object> map, Transformer factory)
        {
            return new LazySortedMap(map, factory);
        }

        //-----------------------------------------------------------------------
        /**
         * Constructor that wraps (not copies).
         * 
         * @param map  the map to decorate, must not be null
         * @param factory  the factory to use, must not be null
         * @throws IllegalArgumentException if map or factory is null
         */
        protected LazySortedMap(java.util.SortedMap<Object, Object> map, Factory factory)
            : base(map, factory)
        {
        }

        /**
         * Constructor that wraps (not copies).
         * 
         * @param map  the map to decorate, must not be null
         * @param factory  the factory to use, must not be null
         * @throws IllegalArgumentException if map or factory is null
         */
        protected LazySortedMap(java.util.SortedMap<Object, Object> map, Transformer factory)
            : base(map, factory)
        {
        }

        //-----------------------------------------------------------------------
        /**
         * Gets the map being decorated.
         * 
         * @return the decorated map
         */
        protected java.util.SortedMap<Object, Object> getSortedMap()
        {
            return (java.util.SortedMap<Object, Object>)map;
        }

        //-----------------------------------------------------------------------
        public Object firstKey()
        {
            return getSortedMap().firstKey();
        }

        public Object lastKey()
        {
            return getSortedMap().lastKey();
        }

        public java.util.Comparator<Object> comparator()
        {
            return getSortedMap().comparator();
        }

        public java.util.SortedMap<Object, Object> subMap(Object fromKey, Object toKey)
        {
            java.util.SortedMap<Object, Object> map = getSortedMap().subMap(fromKey, toKey);
            return new LazySortedMap(map, factory);
        }

        public java.util.SortedMap<Object, Object> headMap(Object toKey)
        {
            java.util.SortedMap<Object, Object> map = getSortedMap().headMap(toKey);
            return new LazySortedMap(map, factory);
        }

        public java.util.SortedMap<Object, Object> tailMap(Object fromKey)
        {
            java.util.SortedMap<Object, Object> map = getSortedMap().tailMap(fromKey);
            return new LazySortedMap(map, factory);
        }

    }
}